home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Sample Code / Music Architecture / Embedding Instruments / BigEasy / BigEasyDialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-18  |  16.8 KB  |  825 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        BigEasyDialogs.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    xxx put writers here xxx
  7.  
  8.     Copyright:    © 1992, 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <8>     5/27/94    dvb        This&that
  13.         <5+>      5/5/93    dvb        Fields & controls.
  14.          <5>      5/5/93    dvb        
  15.          <4>      1/7/93    dvb        Improve number-dialog with +/- keys. Make it compile under mpw.
  16.          <3>     4/13/92    dvb        Allow windows to idle behind dialogue. Pass activate/deactivates
  17.                                     to back windows.
  18.          <2>      4/3/92    dvb        New calls for getting text & numbers.
  19.          <1>     1/20/92    dvb        first checked in
  20.  
  21. */
  22.  
  23. /* file: BigEasyDialogs.c
  24.  *
  25.  * Started 2 Jan 1992, more or less.
  26.  *
  27.  */
  28.  
  29.  
  30. /*--------------------------
  31.     Inclusions
  32. --------------------------*/
  33.  
  34. #include <Windows.h>
  35. #include <Dialogs.h>
  36. #include <Controls.h>
  37. #include <OSUtils.h>
  38. #include <ToolUtils.h>
  39. #include <Resources.h>
  40. #include <TextEdit.h>
  41. #include <Memory.h>
  42. #include <BDC.h>
  43. #include <Packages.h>
  44.  
  45. #include <Icons.h>
  46. #include "BigEasyDialogs.h"
  47. #include "BigEasyTextish.h"
  48. #include "BigEasy2.h"
  49.  
  50. /*--------------------------
  51.     Constants
  52. --------------------------*/
  53.  
  54. #define kButtonHeight 20
  55. #define kButtonWindowMargin 10
  56. #define kButtonTextMargin 20
  57.  
  58. #define    kOSEvent app4Evt            /* event used by MultiFinder */
  59. #define    kSuspendResumeMessage 1        /* high byte of suspend/resume event message */
  60.  
  61. /*--------------------------
  62.     Local Data
  63. --------------------------*/
  64.  
  65. typedef struct
  66.     {
  67.     StringPtr header;
  68.     StringPtr body;
  69.     short iconID;
  70.     } EasyDialogMessageStuff;
  71.  
  72.  
  73. static EasyDialogButtonList dOkayCancelButtonList =
  74.     {
  75.     2,0,1,
  76.     "\pOkay",0,
  77.     "\pCancel",0
  78.     };
  79.  
  80. static EasyDialogButtonList dSaveDiscardCancelButtonList =
  81.     {
  82.     3,0,2,
  83.     "\pSave",0,
  84.     "\pDiscard",'D',
  85.     "\pCancel",0
  86.     };
  87.  
  88. static Boolean gNumbers = false;        /* true if we're getting a number string */
  89.  
  90.  
  91. /*--------------------------
  92.     Local Prototypes
  93. --------------------------*/
  94.  
  95. static void EasyDialogMessageUpdateProc(long refcon,const Rect *updateRect);
  96. static void BlinkButton(ControlHandle buttonControl);
  97. static void BlinkItem(DialogPtr theDialog,short item);
  98. static pascal Boolean MyModalFilterProc(DialogPtr theDialog,
  99.         EventRecord *theEvent, short *itemHit);
  100. static pascal Boolean MyFieldModalFilterProc(DialogPtr theDialog,
  101.         EventRecord *theEvent,short *itemHit);
  102.  
  103. /*--------------------------
  104.     Roughage
  105. --------------------------*/
  106.  
  107. long EasyDialog(Rect *windowRect,
  108.         beDialogUpdate updateProc,
  109.         beDialogKey keyProc,
  110.         beDialogClick clickProc,
  111.         beDialogIdle idleProc,
  112.         EasyDialogButtonList *buttonList,
  113.         long refcon)
  114.     {
  115.     WindowPtr w;
  116.     Rect r,s,updateRect;
  117.     short i;
  118.     short biggestButton,x;
  119.     ControlHandle ch[20];
  120.     Rect defaultButtonRect;
  121.     EventRecord er;
  122.     Boolean done;
  123.     long saveMenus;
  124.     long result;
  125.     long eventCount;
  126.     #pragma unused (clickProc)
  127.  
  128.     HiliteMenu(0);
  129.     r = *windowRect;
  130.  
  131.     if(r.left <= 0)
  132.         {
  133.         s = qd.screenBits.bounds;
  134.  
  135.         OffsetRect(&r,
  136.                 (s.left + s.right - r.left - r.right)/2,
  137.                 (s.top + s.bottom - r.top - r.bottom)/2);
  138.         }
  139.  
  140.     saveMenus = DisableAllMenus();
  141.  
  142.     i = gSystemVersion > 0x700 ? movableDBoxProc : dBoxProc;
  143.  
  144.     if(gHasColor)
  145.         w = NewCWindow(0,&r,"\p",true,i,(WindowPtr)-1,false,0);
  146.     else
  147.         w = NewWindow(0,&r,"\p",true,i,(WindowPtr)-1,false,0);
  148.     SetPort(w);
  149.  
  150.     r.right -= r.left;
  151.     r.bottom -= r.top;
  152.     r.left = r.top = 0;
  153.  
  154.     updateRect = r;
  155.     updateRect.bottom -= 2*kButtonWindowMargin + kButtonHeight;
  156.  
  157.     if((long)buttonList <= 0)
  158.         {
  159.         if(buttonList == kEasyDialogSaveDiscardCancel)
  160.             buttonList = &dSaveDiscardCancelButtonList;
  161.         else
  162.             {    
  163.             if(buttonList == kEasyDialogOkayCancel)
  164.                 {
  165.                 dOkayCancelButtonList.count = 2;
  166.                 dOkayCancelButtonList.defaultButton = 0;
  167.                 dOkayCancelButtonList.cancelButton = 1;
  168.                 }
  169.             else if(buttonList == kEasyDialogCancelOkay)
  170.                 {
  171.                 dOkayCancelButtonList.count = 2;
  172.                 dOkayCancelButtonList.defaultButton = 1;
  173.                 dOkayCancelButtonList.cancelButton = 1;
  174.                 }
  175.             else
  176.                 {
  177.                 dOkayCancelButtonList.count = 1;
  178.                 dOkayCancelButtonList.defaultButton = 0;
  179.                 dOkayCancelButtonList.cancelButton = -1;
  180.                 }
  181.             buttonList = &dOkayCancelButtonList;
  182.             }
  183.         }
  184.  
  185.     if(buttonList->defaultButton >= buttonList->count)
  186.         buttonList->defaultButton = -1;
  187.     if(buttonList->cancelButton >= buttonList->count)
  188.         buttonList->cancelButton = -1;
  189.             
  190.     TextFont(0);
  191.     TextSize(12);
  192.     biggestButton = 0;
  193.     for(i = 0; i<buttonList->count; i++)
  194.         {
  195.         x = StringWidth(buttonList->button[i].name);
  196.         if(x > biggestButton)
  197.             biggestButton = x;
  198.         }
  199.  
  200.     biggestButton += kButtonTextMargin;
  201.  
  202.     s.left = kButtonWindowMargin;
  203.     s.bottom = r.bottom - kButtonWindowMargin;
  204.     s.right = s.left + biggestButton;
  205.     s.top = s.bottom - kButtonHeight;
  206.  
  207.     biggestButton += kButtonWindowMargin;
  208.  
  209.     for(i = 0; i<buttonList->count; i++)
  210.         {
  211.         ch[i] = NewControl(w,&s,buttonList->button[i].name,true,0,0,1,pushButProc,i);
  212.         if(i == buttonList->defaultButton)
  213.             {
  214.             defaultButtonRect = s;
  215.             InsetRect(&defaultButtonRect,-4,-4);
  216.             }
  217.         OffsetRect(&s,biggestButton,0);
  218.         }
  219.  
  220.     done = false;
  221.  
  222.     while(!done)
  223.         {
  224.         if(eventCount ++ & 1)
  225.             {
  226.             if(idleProc)
  227.                 (*idleProc)(refcon);
  228.             IdleWindow(-1);
  229.             }
  230.  
  231.         WaitNextEvent(0xffff,&er,0,nil);
  232.  
  233.         switch (er.what)
  234.             {
  235.             case 0:
  236.                 break;
  237.  
  238.             case mouseDown:
  239.                     {
  240.                     WindowPtr clickWindow;
  241.                     short part;
  242.                     ControlHandle whichControl;
  243.  
  244.                     part = FindWindow (er.where, &clickWindow);
  245.                     if(part == inMenuBar)
  246.                         {
  247.                         long p;
  248.  
  249.                         p = MenuSelect(er.where);
  250.                         }
  251.                     else if(part == inDrag
  252.                             && (clickWindow == w || er.modifiers & cmdKey))
  253.                         DragWindow(clickWindow,er.where,&gBigRect);
  254.                     else if(part != inContent || clickWindow != w)
  255.                         SysBeep(1);
  256.                     else
  257.                         {
  258.                         GlobalToLocal(&er.where);
  259.                         FindControl(er.where,w,&whichControl);
  260.                         if(whichControl)
  261.                             {
  262.                             if(TrackControl(whichControl,er.where,nil))
  263.                                 {
  264.                                 done = true;
  265.                                 result = GetCRefCon(whichControl);
  266.                                 }
  267.                             }
  268.                         }
  269.                     }
  270.                 break;
  271.  
  272.             case activateEvt:
  273.             activateEvent:
  274.                 HandleActivateEvent(&er);
  275.                 InitCursor();
  276.                 break;
  277.  
  278.             case updateEvt:
  279.                 if(er.message != (long)w)
  280.                     {
  281.                     HandleUpdateEvent(&er);
  282.                     SetPort(w);
  283.                     }
  284.                 else
  285.                     {
  286.                     BeginUpdate(w);
  287.                     DrawControls(w);
  288.                     if(buttonList->defaultButton >= 0)
  289.                         {
  290.                         PenSize(3,3);
  291.                         FrameRoundRect(&defaultButtonRect,16,16);
  292.                         PenNormal();
  293.                         }
  294.                     PenPat(&qd.gray);
  295.                     MoveTo(updateRect.left + kButtonWindowMargin,updateRect.bottom);
  296.                     LineTo(updateRect.right - kButtonWindowMargin,updateRect.bottom);
  297.                     PenNormal();
  298.                     if(updateProc)
  299.                         (*updateProc)(refcon,&updateRect);
  300.                     EndUpdate(w);
  301.                     }
  302.                 break;
  303.  
  304.             case keyDown:
  305.                     {
  306.                     er.message &= 0x000000ff;
  307.                     if( (er.message == 13 || er.message == 3)
  308.                             && buttonList->defaultButton >= 0)        /* enter or return */
  309.                         {
  310.                         BlinkButton(ch[buttonList->defaultButton]);
  311.                         done = true;
  312.                         result = buttonList->defaultButton;
  313.                         }
  314.                     else if( ((er.message == '.' && (er.modifiers & cmdKey)) || er.message == 27)
  315.                             && buttonList->cancelButton >= 0)        /* esc or cmd-. */
  316.                         {
  317.                         BlinkButton(ch[buttonList->cancelButton]);
  318.                         done = true;
  319.                         result = buttonList->cancelButton;
  320.                         }
  321.                     else if (er.modifiers & cmdKey)                    /* a key-equiv? */
  322.                         {
  323.                         short capKey;
  324.  
  325.                         capKey = er.message;
  326.                         if(capKey >= 'a' && capKey <= 'z')
  327.                             capKey += 'A' - 'a';
  328.                         for(i = 0; i < buttonList->count; i++)
  329.                             if(capKey == buttonList->button[i].key)
  330.                                 {
  331.                                 BlinkButton(ch[i]);
  332.                                 done = true;
  333.                                 result = i;
  334.                                 }
  335.                             }
  336.                         }
  337.  
  338.                     if(!done)        /* someone snatch the key? */
  339.                         if(keyProc)
  340.                             (*keyProc)(refcon,er.message,er.modifiers);
  341.  
  342.  
  343.                 break;
  344.  
  345.             case kOSEvent:
  346.                 if( (er.message>>24) == kSuspendResumeMessage)
  347.                     goto activateEvent;
  348.                 break;
  349.     
  350.             } /* switch */
  351.         } /* while !done */
  352.  
  353.     DisposeWindow(w);
  354.  
  355.     EnableAllMenus(saveMenus);
  356.  
  357.     return result;
  358.     }
  359.  
  360. short EasyDialogMessage(short iconID,
  361.         StringPtr header,StringPtr body,
  362.         EasyDialogButtonList *buttonList)
  363.     {
  364.     EasyDialogMessageStuff stuff;
  365.     Rect r;
  366.     short result;
  367.  
  368.     stuff.header = header;
  369.     stuff.body = body;
  370.     stuff.iconID = iconID;
  371.  
  372.     r.left = r.top = 0;
  373.     r.right = 420;
  374.     r.bottom = 170;
  375.  
  376.     result = EasyDialog(&r,EasyDialogMessageUpdateProc,nil,nil,nil,buttonList,(long)&stuff);
  377.  
  378.     return result;
  379.     }
  380.  
  381. void EasyDialogMessageUpdateProc(long refcon,const Rect *updateRect)
  382.     {
  383.     EasyDialogMessageStuff *stuff;
  384.     Rect r;
  385.     Handle theIcon;
  386.  
  387.     stuff = (EasyDialogMessageStuff *) refcon;
  388.  
  389.     r.left = r.top = kButtonWindowMargin;
  390.     r.bottom = r.top + 32;
  391.  
  392.     if(stuff->iconID != -1)
  393.         {
  394.         r.right = r.left + 32;
  395.         r.top = kButtonWindowMargin;
  396.         theIcon = GetIcon(stuff->iconID);
  397.         if(theIcon)
  398.             {
  399.             PlotIcon(&r,theIcon);
  400.             ReleaseResource(theIcon);
  401.             }
  402.         else
  403.             PlotIconID(&r,atAbsoluteCenter,0,stuff->iconID);
  404.         }
  405.  
  406.     r.left += 32 + kButtonWindowMargin;
  407.     r.right = updateRect->right - kButtonWindowMargin;
  408.  
  409.     if(stuff->header)
  410.         TextBox(stuff->header+1,stuff->header[0],&r,teJustLeft);
  411.  
  412.     r.top = r.bottom + kButtonWindowMargin;
  413.     r.left = kButtonWindowMargin;
  414.     r.bottom = updateRect->bottom - kButtonWindowMargin;
  415.  
  416.     if(stuff->body)
  417.         TextBox(stuff->body+1,stuff->body[0],&r,teJustLeft);
  418.     }
  419.  
  420.  
  421. void BlinkButton(ControlHandle buttonControl)
  422.     {
  423.     long dummy;
  424.  
  425.     HiliteControl(buttonControl,1);
  426.     Delay(7,&dummy);
  427.     HiliteControl(buttonControl,0);
  428.     }
  429.  
  430.  
  431.  
  432.  
  433.  
  434. Boolean EasyDialogGetString(const StringPtr dialogTitle,
  435.         const StringPtr dialogPrompt,
  436.         StringPtr inOutString,short maxInOutStringLength)
  437. /*
  438.  * The scary thing about this routine is that
  439.  * it requires two resources: DLOG 128 and 129.
  440.  * 128 should use a modal alert-type window,
  441.  * and 129, a moveable-modal.
  442.  *
  443.  * The items should be:
  444.  *        1 - Okay
  445.  *        2 - Cancel
  446.  *        3 - Title static text = "^0"
  447.  *        4 - Prompt static text = "^1"
  448.  *        5 - Edit text field for entry
  449.  */
  450.     {
  451.     DialogPtr dp;
  452.     short hit;
  453.     short itemType;
  454.     Rect itemRect;
  455.     Handle itemHandle;
  456.     Boolean result;
  457.     Str255 outString;
  458.  
  459.     ParamText(dialogTitle,dialogPrompt,0,0);
  460.  
  461.     dp = GetNewDialog(128,0,(WindowPtr)-1);            //!!! should have two kinds
  462.     if(!dp)
  463.         {
  464.         SysBeep(2);
  465.         return false;
  466.         }
  467.  
  468.     GetDItem(dp,5,&itemType,&itemHandle,&itemRect);
  469.     SetIText(itemHandle,inOutString);
  470.     SelIText(dp,5,0,32767);
  471.     ModalDialog(MyModalFilterProc,&hit);
  472.     (0,&hit);
  473.  
  474.     if(hit == 1)        /* Okay */
  475.         {
  476.         GetIText(itemHandle,outString);
  477.         if(outString[0] > maxInOutStringLength)
  478.             outString[0] = maxInOutStringLength;
  479.         BlockMove(outString,inOutString,maxInOutStringLength+1);
  480.         result = true;
  481.         }
  482.     else
  483.         result = false;
  484.     DisposeDialog(dp);
  485.  
  486.     return result;
  487.     }
  488.  
  489.  
  490. void BlinkItem(DialogPtr theDialog,short item)
  491.     {
  492.     ControlHandle button;
  493.     short itemType;
  494.     Rect itemRect;
  495.  
  496.     GetDItem(theDialog,item,&itemType,(void *)&button,&itemRect);
  497.     BlinkButton(button);
  498.     }
  499.  
  500.  
  501. pascal Boolean MyModalFilterProc(DialogPtr theDialog,
  502.         EventRecord *theEvent,short *itemHit)
  503.     {
  504.     short key;
  505.     Boolean result;
  506.     short itemType;
  507.     Rect itemRect;
  508.     Handle itemHandle;
  509.     short bump;
  510.     Str255 str;
  511.     long x;
  512.  
  513.     IdleWindow(-1);
  514.  
  515.     result = false;
  516.     switch(theEvent->what)
  517.         {
  518.         case keyDown:
  519.         case autoKey:
  520.             key = theEvent->message & 0xFF;
  521.             if(key == 27 || (key == '.' && (theEvent->modifiers & cmdKey)))
  522.                 {
  523.                 result = true;
  524.                 *itemHit = 2;
  525.                 BlinkItem(theDialog,2);
  526.                 }
  527.             else if(key == 3 || key == 13)
  528.                 {
  529.                 result = true;
  530.                 *itemHit = 1;
  531.                 BlinkItem(theDialog,1);
  532.                 }
  533.             else if((key =='a' || key == 'A') && (theEvent->modifiers &cmdKey))
  534.                 {
  535.                 SelIText(theDialog,5,0,32767);
  536.                 theEvent->what = 0;
  537.                 }
  538.             else if(gNumbers && (key == '+' || key == '=')
  539.                     && (theEvent->modifiers & cmdKey))
  540.                 {
  541.                 bump = 1;
  542.  
  543.         bumpString:
  544.                 if(theEvent->modifiers & shiftKey)
  545.                     bump *= 10;
  546.  
  547.                 GetDItem(theDialog,5,&itemType,&itemHandle,&itemRect);
  548.                 GetIText(itemHandle,str);
  549.                 StringToNum(str,&x);
  550.                 x += bump;
  551.                 NumToString(x,str);
  552.                 SetIText(itemHandle,str);
  553.                 SelIText(theDialog,5,0,32767);
  554.                 theEvent->what = 0;
  555.                 }
  556.             else if(gNumbers && (key == '-' || key == '_')
  557.                     && (theEvent->modifiers & cmdKey))
  558.                 {
  559.                 bump = -1;
  560.                 goto bumpString;
  561.                 }
  562.             break;
  563.  
  564.         case updateEvt:
  565.             if(theEvent->message != (long)theDialog)
  566.                 HandleUpdateEvent(theEvent);
  567.             else
  568.                 {
  569.                 GrafPort *oldPort;
  570.                 GetPort(&oldPort);
  571.                 SetPort(theDialog);
  572.                 GetDItem(theDialog,1,&itemType,&itemHandle,&itemRect);
  573.                 InsetRect(&itemRect,-4,-4);
  574.                 PenSize(3,3);
  575.                 FrameRoundRect(&itemRect,16,16);
  576.                 PenNormal();
  577.                 SetPort(oldPort);
  578.                 }
  579.             break;
  580.  
  581.         case mouseDown:
  582.                 {
  583.                 WindowPtr clickWindow;
  584.                 short part;
  585.                 
  586.                 part = FindWindow (theEvent->where, &clickWindow);
  587.                 if(part == inDrag
  588.                         && (clickWindow == theDialog || theEvent->modifiers & cmdKey))
  589.                     {
  590.                     theEvent->what = 0;
  591.                     DragWindow(clickWindow,theEvent->where,&gBigRect);
  592.                     }
  593.                 }
  594.             break;
  595.         }
  596.  
  597. goHome:
  598.     return result;
  599.     }
  600.  
  601.  
  602. Boolean EasyDialogGetNumber(const StringPtr dialogTitle,
  603.         const StringPtr dialogPrompt,
  604.         long *inOutNumber)
  605.     {
  606.     Str255 numString;
  607.     Boolean result;
  608.  
  609.     NumToString(*inOutNumber,numString);
  610.  
  611.     gNumbers = true;
  612.     result = EasyDialogGetString(dialogTitle,dialogPrompt,numString,31);
  613.     gNumbers = false;
  614.  
  615.     if(result)
  616.         StringToNum(numString,inOutNumber);
  617.     return result;
  618.     }
  619.  
  620. static EasyFieldList *fieldList;
  621.  
  622. Boolean EasyFieldDialog(short dialogID,EasyFieldList *fieldList,void *data,
  623.         StringPtr dialogTitle)
  624.     {
  625.     DialogPtr dp;
  626.     short hit;
  627.     short itemType;
  628.     Rect itemRect;
  629.     Handle itemHandle;
  630.     Boolean result;
  631.     Str255 aString;
  632.     EasyField *field;
  633.     long *w;
  634.     short j,x;
  635.     short firstTextItem;
  636.  
  637.     result = true;
  638.  
  639.     dp = GetNewDialog(dialogID,0,(WindowPtr)-1);
  640.     if(!dp)
  641.         {
  642.         SysBeep(2);
  643.         return false;
  644.         }
  645.  
  646.     if(dialogTitle)
  647.         SetWTitle(dp,dialogTitle);
  648.  
  649.     w = data;
  650.     field = fieldList->field;
  651.     firstTextItem = 0;
  652.  
  653.     while(field->itemNumber)
  654.         {
  655.         switch(field->itemType)
  656.             {
  657.             case easyRadioGroup:
  658.                 for(j = 0; j < field->itemCount; j++)
  659.                     {
  660.                     GetDItem(dp,field->itemNumber + j,
  661.                             &itemType,&itemHandle,&itemRect);
  662.                     if(itemType == ctrlItem + radCtrl)
  663.                         SetCtlValue((ControlHandle)itemHandle,
  664.                                 j+1 == *w ? 1 : 0);
  665.                     }
  666.                 w++;
  667.                 break;
  668.  
  669.             case easyCheckbox:
  670.                 GetDItem(dp,field->itemNumber,
  671.                         &itemType,&itemHandle,&itemRect);
  672.                 if(itemType == ctrlItem + chkCtrl)
  673.                     SetCtlValue((ControlHandle)itemHandle, *w);
  674.                 w++;
  675.                 break;
  676.  
  677.             case easyTextNumber:
  678.                 FixedPointToPString(*w,field->general ? 4 : 0,field->general,aString);
  679.                 GetDItem(dp,field->itemNumber,
  680.                         &itemType,&itemHandle,&itemRect);
  681.                 if(itemType == editText)
  682.                     SetIText(itemHandle,aString);
  683.  
  684.                 if(!firstTextItem)
  685.                     {
  686.                     SelIText(dp,field->itemNumber,0,32767);
  687.                     firstTextItem = field->itemNumber;
  688.                     }
  689.                 w++;
  690.                 break;
  691.  
  692.             case easyTextString:
  693.                 GetDItem(dp,field->itemNumber,
  694.                         &itemType,&itemHandle,&itemRect);
  695.                 if(itemType == editText)
  696.                     SetIText(itemHandle,(StringPtr)w);
  697.  
  698.                 if(!firstTextItem)
  699.                     {
  700.                     SelIText(dp,field->itemNumber,0,32767);
  701.                     firstTextItem = field->itemNumber;
  702.                     }
  703.                 w += 64;
  704.                 break;
  705.  
  706.             default:
  707.                 break;
  708.             }
  709.         field++;
  710.         }
  711.  
  712.     ShowWindow(dp);
  713.  
  714.     do
  715.         {
  716.         ModalDialog(MyModalFilterProc,&hit);
  717.         field = fieldList->field;
  718.         while(field->itemNumber)
  719.             {
  720.             if(field->itemNumber <= hit
  721.                     && hit < field->itemNumber+field->itemCount)
  722.                 {
  723.                 switch(field->itemType)
  724.                     {
  725.                     case easyRadioGroup:
  726.                         for(j = 0; j < field->itemCount; j++)
  727.                             {
  728.                             GetDItem(dp,field->itemNumber + j,
  729.                                     &itemType,&itemHandle,&itemRect);
  730.                             if(itemType == ctrlItem + radCtrl)
  731.                                 SetCtlValue((ControlHandle)itemHandle,
  732.                                         j+field->itemNumber == hit ? 1 : 0);
  733.                             }
  734.                         break;
  735.         
  736.                     case easyCheckbox:
  737.                         GetDItem(dp,hit,
  738.                                 &itemType,&itemHandle,&itemRect);
  739.                         if(itemType == ctrlItem + chkCtrl)
  740.                             SetCtlValue((ControlHandle)itemHandle,
  741.                                     !GetCtlValue((ControlHandle)itemHandle));
  742.                         break;
  743.  
  744.                     }
  745.                 goto didHit;
  746.                 }
  747.             field++;
  748.             }
  749. didHit:
  750.         if(hit == 1 || hit == fieldList->cancelButton)
  751.             goto doneDialog;
  752.         } while(1);
  753.  
  754. doneDialog:
  755.     if(hit != 1)        /* Okay */
  756.         result = false;
  757.  
  758.     if(result)
  759.         {
  760.         w = data;
  761.         field = fieldList->field;
  762.         while(field->itemNumber)
  763.             {
  764.             switch(field->itemType)
  765.                 {
  766.                 case easyRadioGroup:
  767.                     for(j = 0; j < field->itemCount; j++)
  768.                         {
  769.                         GetDItem(dp,field->itemNumber + j,
  770.                                 &itemType,&itemHandle,&itemRect);
  771.                         if(itemType == ctrlItem + radCtrl)
  772.                             {
  773.                             x = GetCtlValue((ControlHandle)itemHandle);
  774.                             if(x)
  775.                                 *w = j+1;
  776.                             }
  777.                         }
  778.                     w++;
  779.                     break;
  780.     
  781.                 case easyCheckbox:
  782.                     GetDItem(dp,field->itemNumber,
  783.                             &itemType,&itemHandle,&itemRect);
  784.                     if(itemType == ctrlItem + chkCtrl)
  785.                         *w = GetCtlValue((ControlHandle)itemHandle);
  786.                     w++;
  787.                     break;
  788.     
  789.                 case easyTextNumber:
  790.                     GetDItem(dp,field->itemNumber,
  791.                             &itemType,&itemHandle,&itemRect);
  792.                     if(itemType == editText)
  793.                         {
  794.                         GetIText(itemHandle,aString);
  795.                         PStringToFixedPoint(aString,
  796.                                 field->general ? 5 : 0,field->general,w);
  797.                         }
  798.                     w++;
  799.                     break;
  800.     
  801.                 case easyTextString:
  802.                     GetDItem(dp,field->itemNumber,
  803.                             &itemType,&itemHandle,&itemRect);
  804.                     if(itemType == editText)
  805.                         GetIText(itemHandle,(StringPtr)w);
  806.                     w += 64;
  807.                     break;
  808.     
  809.                 default:
  810.                     break;
  811.                 }
  812.             field++;
  813.             }
  814.         }
  815.  
  816.     DisposeDialog(dp);
  817.  
  818.  
  819.  
  820.     return result;
  821.     }
  822.  
  823.  
  824.  
  825.